package cn.sykj.car.service.impl;

import cn.sykj.car.common.Const;
import cn.sykj.car.common.StatusCode;
import cn.sykj.car.entity.Roles;
import cn.sykj.car.entity.UserRole;
import cn.sykj.car.entity.Users;
import cn.sykj.car.exception.CommonException;
import cn.sykj.car.exception.ParameterInvalidException;
import cn.sykj.car.exception.UserCreateFailException;
import cn.sykj.car.exception.UserDuplicateException;
import cn.sykj.car.mapper.UsersMapper;
import cn.sykj.car.service.IRolesService;
import cn.sykj.car.service.IUserRoleService;
import cn.sykj.car.service.IUsersService;
import cn.sykj.car.utils.Utils;
import cn.sykj.car.vo.UsersVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.util.*;

/**
 * <p>
 * 用户 服务实现类
 * </p>
 *
 * @author Yixu
 * @since 2018-11-29
 */
@Service
public class UsersServiceImpl extends ServiceImpl<UsersMapper, Users> implements IUsersService {

    @Resource
    private IUserRoleService iUserRoleService;

    @Resource
    private IRolesService iRolesService;

    @Override
    public Users getUserByName(String userName) {
        UsersVO condition = new UsersVO();
        condition.setUserName(userName);
        QueryWrapper<Users> queryWrapper = new QueryWrapper<>();
        queryWrapper.setEntity(condition);
        Users users = this.getOne(queryWrapper);
        return users;
    }

    /**
     * 添加用户
     *
     * @param users
     * @return
     * @throws Exception
     * @author yuhao
     * @version 2018-12-05 11:52
     */
    @Override
    @Transactional(rollbackFor = {Exception.class,RuntimeException.class})
    public boolean insertUsers(UsersVO users) throws Exception {
        if (Utils.isEmpty(users)) {
            throw new ParameterInvalidException();
        }
        List<Users> searchUsers;

        // 判断用户名是否重复
        if (Utils.notEmpty(users.getUserName())) {
            QueryWrapper<Users> condition = new QueryWrapper<>();
            condition.eq(Users.USER_NAME, users.getUserName());
            searchUsers = this.list(condition);
            if (searchUsers.size() > 0) {
                throw  new UserDuplicateException();
            }
        }

        // 添加用户、添加角色
        boolean createUserFlag = this.save(users);
        if (createUserFlag) {
            List<Integer> roleIds = users.getRoleIds();
            List<UserRole> userRoles = new ArrayList<>();
            for (Integer roleId : roleIds) {
                UserRole nUserRole = new UserRole();
                nUserRole.setRoleId(roleId);
                nUserRole.setUserId(users.getId());
                userRoles.add(nUserRole);
            }

            // 批量插入
            boolean createUserRoleFlag = iUserRoleService.saveBatch((Collection) userRoles);
            if (!createUserRoleFlag) {
                throw new UserCreateFailException();
            }
        }

        return true;
    }




    /**
     * 修改用户
     *
     * @param users
     * @return
     * @throws Exception
     * @author yuhao
     * @version 2018-12-05 11:52
     */
    @Override
    @Transactional(rollbackFor = {Exception.class,RuntimeException.class})
    public boolean updateUsers(UsersVO users) throws Exception {

        if (Utils.isEmpty(users) || Utils.isEmpty(users.getId())) {
            throw new ParameterInvalidException();
        }

        // 查询用户是否存在
        Users oUser = this.getById(users.getId());
        if (Utils.isEmpty(oUser)||oUser.getDelFlag().equals(Const.DEL_FLAG_TRUE)) {
            throw new CommonException(StatusCode.USER_NOT_FOUND.getCode(),StatusCode.USER_NOT_FOUND.getMsg());
        }

        List<Users> searchUsers;

        // 判断除本身外用户名是否重复
        if (Utils.notEmpty(users.getUserName())) {
            QueryWrapper<Users> condition = new QueryWrapper<>();
            condition.eq(Users.USER_NAME, users.getUserName()).ne(Users.ID, users.getId());
            searchUsers = this.list(condition);
            if (searchUsers.size() > 0) {
                throw new CommonException(StatusCode.USER_NAME_REPEAT.getCode(),StatusCode.USER_NAME_REPEAT.getMsg());
            }
        }


        // 修改用户、修改角色
        boolean updateUserFlag = this.saveOrUpdate(users);
        boolean updateUserRoleFlag = true;
        if (updateUserFlag) {
            Map<String,Object> deleteMap = new HashMap<>();
            deleteMap.put(UserRole.USER_ID,users.getId());

            List<Integer> roleIds = users.getRoleIds();
            List<UserRole> userRoles = new ArrayList<>();
            for (Integer roleId : roleIds) {
                UserRole nUserRole = new UserRole();
                nUserRole.setRoleId(roleId);
                nUserRole.setUserId(users.getId());
                userRoles.add(nUserRole);
            }

            // 删除原角色
            iUserRoleService.removeByMap(deleteMap);

            // 批量插入
            updateUserRoleFlag = iUserRoleService.saveBatch((Collection) userRoles);
        }


        if (!updateUserFlag || !updateUserRoleFlag) {
            // 回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }

        return true;
    }

    /**
     * 删除用户
     *
     * @param users 根据id删除菜单
     * @return
     * @throws Exception
     * @author yuhao
     * @version 2018-12-05 11:52
     */
    @Override
    @Transactional(rollbackFor = {Exception.class,RuntimeException.class})
    public boolean deleteUsers(UsersVO users) throws Exception {

        // 参数不存在
        if (Utils.isEmpty(users) || Utils.isEmpty(users.getId())) {
            throw new ParameterInvalidException();
        }

        // 判断当前用户是否已不存在
        QueryWrapper<Users> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(Users.DEL_FLAG, 0).eq(Users.ID, users.getId());
        Users oUsers = this.getOne(queryWrapper);
        if (Utils.isEmpty(oUsers)) {
            throw new CommonException(StatusCode.USER_NOT_FOUND.getCode(),StatusCode.USER_NOT_FOUND.getMsg());
        }

        boolean ret = this.removeById(oUsers);
        return ret;
    }

    /**
     * 查看单个用户
     *
     * @param users
     * @return
     * @author yuhao
     * @version 2018-12-05 11:52
     */
    @Override
    public UsersVO selectOneUsers(UsersVO users) throws InvocationTargetException, IllegalAccessException {
        Users nUser = this.getById(users);

        // 查询已添加的角色
        List<Roles> rolesList = iRolesService.getRolesByUser(users.getId());
        UsersVO usersVO = new UsersVO();
        BeanUtils.copyProperties(usersVO, users);
        usersVO.setYtjRoles(rolesList);

        // 查询未添加的角色
//        List<Roles> rolesList1 = iRolesService.getWtjRolesByUser(users.getId());
//        nUser.setWtjRoles(rolesList1);

        return usersVO;
    }

    /**
     * 分页查看用户
     *
     * @param page      分页器
     * @param condition 查询条件
     * @return
     * @author yuhao
     * @version 2018-12-05 11:52
     */
    @Override
    public Page<UsersVO> pageUsers(Page<UsersVO> page, UsersVO condition) {

        List<UsersVO> usersList = this.baseMapper.findUsers(page,condition);
        for(UsersVO users:usersList){

            // 查询已添加的角色
            List<Roles> rolesList = iRolesService.getRolesByUser(users.getId());
            users.setYtjRoles(rolesList);

        }
        page.setRecords(usersList);

        return page;
    }

    /**
     * 根据角色id查询用户
     *
     * @param roleId
     * @return
     * @author yuhao 2018-12-07 15:56
     */
    @Override
    public List<Users> selectUsersByRoleId(Integer roleId) {
        return baseMapper.selectUsersByRoleId(roleId);
    }

}
